package hamsterwrench.data.lump;

import java.io.*;

/**
 * @author Matt
 *
 */
public class LumpDataManager {

	private DataInputStream din;
	private DataOutputStream don;
	private boolean inWriteMode;

	public LumpDataManager(InputStream i){
		din = new DataInputStream(i);
	}

	/**
	 * Returns a short with a value of an unsigned byte from the lump file.
	 * @param i The InputStream to read from
	 * @return the read byte as a short
	 * @throws IOException
	 */
	public short readByte() throws IOException{
		return (short)din.readUnsignedByte();
	}

	public short readShort() throws IOException{
		return din.readShort();
	}

	public int readLong() throws IOException{
		return din.readInt();
	}

	public float readFloat() throws IOException{
		return din.readFloat();
	}


	public String readZstr() throws IOException{
		char x = din.readChar();
		StringBuilder sb = new StringBuilder();
		while (x > 0){
			sb.append((char)x);
			x = din.readChar();
		}
		return sb.toString();
	}

	public String readVstri() throws IOException{
		int c = din.readShort();
		StringBuilder sb = new StringBuilder(c);
		int x = din.read();
		for(int i = 0; i < c; i++){
			if(x > 0){
				sb.append((char)x);
				x = din.read();
			}else{
				System.err.println("ERROR: EOF or NUL encountered before expected end of VSTR");
				break;
			}
		}
		return sb.toString();
	}

	public String readVstrb() throws IOException{
		int c = din.readUnsignedByte();
		StringBuilder sb = new StringBuilder(c);
		int x = din.read();
		for(int i = 0; i < c; i++){
			if(x > 0){
				sb.append((char)x);
				x = din.read();
			}else{
				System.err.println("ERROR: EOF or NUL encountered before expected end of VSTR");
				break;
			}
		}
		return sb.toString();
	}

	public String readFVStri(int l) throws IOException{
		int c = din.readShort();
		StringBuilder sb = new StringBuilder(c);
		int x = din.readShort();
		for(int i = 0; i < l; i++){
			if(x > 0){
				sb.append((char)x);
				x = din.readShort();
			}else{
				System.err.println("ERROR: EOF or NUL encountered before expected end of FVSTR");
				break;
			}
		}
		din.skip(c - l);
		return sb.toString();
	}

	public String readFVStrb(int l) throws IOException{
		int c = din.read();
		StringBuilder sb = new StringBuilder(c);
		int x = din.readShort();
		for(int i = 0; i < l; i++){
			if(x > 0){
				sb.append((char)x);
				x = din.readShort();
			}else{
				System.err.println("ERROR: EOF or NUL encountered before expected end of FVSTR");
				break;
			}
		}
		din.skip(c - l);
		return sb.toString();
	}
	
	public int readVLI() throws IOException{
		boolean isNegative = false;
		int b = 0;
		int result;

		b = din.read();

		if((b & 64) != 0){
			isNegative = true;
		}

		result = b & 63;

		if((b & 128) != 0){
			result = result * 64;
		}

		while((b & 128) != 0){
			b = din.read();
			result += (b & 127);

			if((b & 128) != 0){
				result = result * 128;
			}
		}

		if(isNegative){
			result = result * -1;
		}

		return result;

	}

	public void writeVLI(OutputStream o, int number) throws IOException{
		boolean isNegative;
		int b = 0;

		if(number < 0){
			isNegative = true;
			number = -1* number;
		}else{
			isNegative = false;
		}

		b = number & 63;
		number = number / 64;
		if(isNegative){
			b = b | Integer.parseInt("1000000", 2);

		}
		if(number > 0){
			b = b | Integer.parseInt("10000000", 2);
		}

		o.write(b);

		while(number > 0){
			b = number & 127;
			number = number / 128;

			if(number > 0){
				b = b | Integer.parseInt("10000000", 2);
			}
			o.write(b);
		}
	}
}
